package com.xbongbong.pro.statistic.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.ExportFormDataVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.statistic.abstracts.AbstractChartExport;
import com.xbongbong.pro.statistic.enums.StatisticsTypeEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.help.ChartExportHelp;
import com.xbongbong.pro.statistic.model.ChartCustomModel;
import com.xbongbong.pro.statistic.model.ChartModel;
import com.xbongbong.pro.statistic.result.pojo.PkInfoPojo;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartPenetrateResultDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultCallStatisticsDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultDTO;
import com.xbongbong.pro.statistic.result.pojo.vo.CallStatisticsVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultVO;
import com.xbongbong.pro.statistic.result.pojo.vo.PerformanceFinishVO;
import com.xbongbong.pro.statistic.service.ChartExportService;
import com.xbongbong.pro.statistic.service.ChartResultService;
import com.xbongbong.pro.statistic.service.HandleImportService;
import com.xbongbong.pro.statistic.service.ResultThroughService;
import com.xbongbong.pro.statistic.through.pojo.dto.ResultThroughDTO;
import com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.export.ImportConstant;
import com.xbongbong.sys.enums.CompanyStructTypeEnum;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author zhouwq
 * @date 2019/6/10 8:57
 */

@Service("chartExportService")
public class ChartExportServiceImpl extends AbstractChartExport implements ChartExportService {

    private static final Logger LOG = LoggerFactory.getLogger(ChartExportServiceImpl.class);

    @Resource
    private HandleImportService handleImportService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private ChartExportHelp chartExportHelp;
    @Resource
    private ResultThroughService resultThroughService;
    @Resource
    private ChartResultService chartResultService;
    @Resource
    private ChartCustomModel chartCustomModel;
    @Resource
    private ChartModel chartModel;


    @Override
    public ExportFormDataVO exportChartThroughData(ResultThroughDTO resultThroughDTO){
        ExportFormDataVO exportFormDataVO = new ExportFormDataVO();
        try {
            FormDataListDTO formDataListDTO = new FormDataListDTO();
            if (Objects.equals(resultThroughDTO.getStatisticsType(), StatisticsTypeEnum.CUSTOM_STATISTIC.getCode())) {
                String hashKey = resultThroughDTO.getCorpid() + "_" + resultThroughDTO.getUserId();
                paasRedisHelper.removeValue(RedisPrefixConstant.EXPORT_STATUS_KEY, hashKey);
                LOG.info("导出失败,接口入口错误");
                return exportFormDataVO;
            }
            chartExportHelp.initChartExport(formDataListDTO, resultThroughDTO.getUserId(), resultThroughDTO.getCorpid());
            //导出标记
            resultThroughDTO.setExportFlag(true);
            ResultThroughVO resultThroughVO = resultThroughService.chartResultThrough(resultThroughDTO);

            SXSSFWorkbook workbook = new SXSSFWorkbook();
            CellStyle style = workbook.createCellStyle();
            SXSSFSheet sheet = workbook.createSheet();
            //垂直水平居中
            chartExportHelp.setWorkBookStyle(style, sheet);
            chartExportHelp.exportThroughChartTableAssemble(resultThroughVO, sheet, style);
            exportFormDataVO.setWorkbook(workbook);
            exportFormDataVO.setName(resultThroughVO.getHead() + ImportConstant.EXCEL_SUFFIX);
            // OSS上传文件
            String downloadUrl = handleImportService.exportAsync(formDataListDTO, exportFormDataVO, ImportConstant.EXCEL_SUFFIX);
            exportFormDataVO.setUrl(downloadUrl);
        }catch (XbbException e){
            String hashKey = resultThroughDTO.getCorpid() + "_" + resultThroughDTO.getUserId();
            paasRedisHelper.removeValue(RedisPrefixConstant.EXPORT_STATUS_KEY, hashKey);
            LOG.error("导出失败", e);
        }
        //导出报表
        return exportFormDataVO;
    }

    @Override
    public ExportFormDataVO exportPkChartData(ChartResultDTO chartResultDTO){
        ExportFormDataVO exportFormDataVO = new ExportFormDataVO();
        try {
            ChartResultPkVO chartResultPkVO = chartResultService.chartResultRulePk(chartResultDTO);
            if (chartResultPkVO != null && chartResultPkVO.getChartList() != null) {
                FormDataListDTO formDataListDTO = new FormDataListDTO();
                chartExportHelp.initChartExport(formDataListDTO, chartResultDTO.getUserId(), chartResultDTO.getCorpid());
                SXSSFWorkbook workbook = new SXSSFWorkbook();
                CellStyle style = workbook.createCellStyle();
                SXSSFSheet sheet = workbook.createSheet();
                //垂直水平居中
                chartExportHelp.setWorkBookStyle(style, sheet);
                List<ChartResultPkDetailVO> results = chartResultPkVO.getChartList();
                results.forEach(result -> {
                    List<String> titleList = new ArrayList<>();
                    titleList.add(I18nMessageUtil.getMessage(CommonConstant.EMPLOYEE));
                    titleList.add(I18nMessageUtil.getMessage(CommonConstant.DEPARTMENT));
                    titleList.add(result.getName() + "(" + result.getUnit() + ")");
                    titleList.add(I18nMessageUtil.getMessage(CommonConstant.RANK));
                    List<PkInfoPojo> dataLists = result.getPkData();
                    chartExportHelp.exportPkChartDataAssemble(titleList, dataLists, sheet, style);
                    exportFormDataVO.setName(I18nMessageUtil.getMessage(CommonConstant.EMPLOYEE) + result.getName() + I18nMessageUtil.getMessage(CommonConstant.PK_LIST) + DateTimeUtil.getString(DateTimeUtil.SDFDate));
                });
                exportFormDataVO.setWorkbook(workbook);
                exportFormDataVO.setName(exportFormDataVO.getName().replaceAll("\\+","+") + ImportConstant.EXCEL_SUFFIX);
                // OSS上传文件
                String downloadUrl = handleImportService.exportAsync(formDataListDTO, exportFormDataVO, ImportConstant.EXCEL_SUFFIX);
                exportFormDataVO.setUrl(downloadUrl);
            }
        }catch (XbbException e){
            String hashKey = chartResultDTO.getCorpid() + "_" + chartResultDTO.getUserId();
            paasRedisHelper.removeValue(RedisPrefixConstant.EXPORT_STATUS_KEY, hashKey);
            LOG.error("导出失败", e);
        }
        return exportFormDataVO;
    }

    @Override
    public ExportFormDataVO exportPerformance(ChartResultDTO chartResultDTO) throws XbbException {
        ExportFormDataVO exportFormDataVO = new ExportFormDataVO();
        try {
            FormDataListDTO formDataListDTO = new FormDataListDTO();
            chartExportHelp.initChartExport(formDataListDTO, chartResultDTO.getUserId(), chartResultDTO.getCorpid());
            chartResultDTO.setPageSize(SizeConstant.PAGE_SIZE);
            //导出标记
            chartResultDTO.setExportFlag(true);
            SXSSFWorkbook workbook = new SXSSFWorkbook();
            CellStyle style = workbook.createCellStyle();
            //垂直水平居中
            style.setAlignment(HorizontalAlignment.CENTER);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            SXSSFSheet sheet = workbook.createSheet();
            PerformanceFinishVO performanceFinishVO = chartResultService.chartResultPerformanceFinish(chartResultDTO);
            int companyStructType = chartResultDTO.getCompanyStructType();
            if (Objects.equals(companyStructType, CompanyStructTypeEnum.USER.getCode())) {
                exportFormDataVO.setName(I18nMessageUtil.getMessage(I18nStringConstant.GOAL_COMPLETION_EMPLOYEE));
                chartExportHelp.exportPerformanceFinishUser(performanceFinishVO, sheet, style);
            } else if (Objects.equals(companyStructType, CompanyStructTypeEnum.DEPARTMENT.getCode())) {
                chartExportHelp.exportPerformanceFinishDep(performanceFinishVO, sheet, style);
                exportFormDataVO.setName(I18nMessageUtil.getMessage(I18nStringConstant.GOAL_COMPLETION_DEPARTMENT));
            }
            exportFormDataVO.setWorkbook(workbook);
            exportFormDataVO.setName(exportFormDataVO.getName() + ImportConstant.EXCEL_SUFFIX);
            // OSS上传文件
            String downloadUrl = handleImportService.exportAsync(formDataListDTO, exportFormDataVO, ImportConstant.EXCEL_SUFFIX);
            exportFormDataVO.setUrl(downloadUrl);
        }catch (XbbException e){
            String hashKey = chartResultDTO.getCorpid() + "_" + chartResultDTO.getUserId();
            paasRedisHelper.removeValue(RedisPrefixConstant.EXPORT_STATUS_KEY, hashKey);
            LOG.error("导出失败", e);
            throw e;
        }
        return exportFormDataVO;
    }

    /**
     * 导出呼叫统计
     *
     * @param chartResultDTO 入参
     * @return com.xbongbong.paas.pojo.vo.ExportFormDataVO
     * @throws XbbException error
     * @author youli.chen
     * @date 2019/6/20 15:58
     * @since v1.0
     */
    @Override
    public ExportFormDataVO exportCallStatistics(ChartResultCallStatisticsDTO chartResultDTO) throws XbbException {
        ExportFormDataVO exportFormDataVO = new ExportFormDataVO();
        try {
            FormDataListDTO formDataListDTO = new FormDataListDTO();
            String corpid = chartResultDTO.getCorpid();
            chartExportHelp.initChartExport(formDataListDTO, chartResultDTO.getUserId(), corpid);
            chartResultDTO.setPageSize(SizeConstant.PAGE_SIZE);
            //导出标记
            chartResultDTO.setExportFlag(true);
            SXSSFWorkbook workbook = new SXSSFWorkbook();
            CellStyle style = workbook.createCellStyle();
            //垂直水平居中
            style.setAlignment(HorizontalAlignment.CENTER);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            SXSSFSheet sheet = workbook.createSheet();
            CallStatisticsVO callStatisticsVO = chartResultService.chartResultCallStatistics(chartResultDTO);
            ChartEntity chartEntity = chartModel.getByKey(callStatisticsVO.getChartId(), corpid);
            boolean outOrIn = true;
            if(Objects.equals(chartEntity.getSystemCode(), SystemCodeEnum.CALL_STAFF_INBOUND.getSystemCode())){
                exportFormDataVO.setName(I18nMessageUtil.getMessage(SystemCodeEnum.CALL_STAFF_INBOUND.getName()));
                outOrIn = false;
            }
            if(Objects.equals(chartEntity.getSystemCode(), SystemCodeEnum.CALL_STAFF_OUTBOUND.getSystemCode())){
                exportFormDataVO.setName(I18nMessageUtil.getMessage(SystemCodeEnum.CALL_STAFF_OUTBOUND.getName()));
                outOrIn = true;
            }

            CallStatisticsVO totalVO = chartResultService.chartResultCallStatisticsTotal(chartResultDTO);
            JSONObject totalData = totalVO.getData() == null ? new JSONObject() : totalVO.getData().getJSONObject(0);
            JSONArray callArry = callStatisticsVO.getData();
            if(callArry == null){
                callArry = new JSONArray();
            } else {
                callArry.add(totalData);
                callStatisticsVO.setData(callArry);
            }
            chartExportHelp.exportCallStatistics(callStatisticsVO, outOrIn, sheet, style);

            exportFormDataVO.setWorkbook(workbook);
            exportFormDataVO.setName(exportFormDataVO.getName() + ImportConstant.EXCEL_SUFFIX);
            // OSS上传文件
            String downloadUrl = handleImportService.exportAsync(formDataListDTO, exportFormDataVO, ImportConstant.EXCEL_SUFFIX);
            exportFormDataVO.setUrl(downloadUrl);
        }catch (XbbException e){
            String hashKey = chartResultDTO.getCorpid() + "_" + chartResultDTO.getUserId();
            paasRedisHelper.removeValue(RedisPrefixConstant.EXPORT_STATUS_KEY, hashKey);
            LOG.error("导出失败", e);
        }
        return exportFormDataVO;
    }

    @Override
    public void initExportConfig(ChartPenetrateResultDTO chartResultDTO) throws XbbException {
        //分页
        chartResultDTO.setPageSize(10000);
        chartResultDTO.setPage(BasicConstant.ONE);
    }

    @Override
    public ChartResultVO getBaseExportData(ChartPenetrateResultDTO chartResultDTO) throws XbbException {
        ChartResultVO chartResultVO;
        //判断是否不是穿透导出
        boolean isNotPenetrate = chartResultDTO.getPenetrateCondition() == null && "".equals(chartResultDTO.getSelectedAxis()) && "".equals(chartResultDTO.getSelectedLegend());
        //判断是否为系统图表导出
        boolean isSys = Objects.equals(chartResultDTO.getStatisticsType(), StatisticsTypeEnum.SYSTEM_STATISTIC.getCode());
        //联动相关解析下放到渲染或穿透逻辑中处理
        if(isNotPenetrate || isSys){
            chartResultVO = chartResultService.chartResult(chartResultDTO);
        }else{
            chartExportHelp.replaceCharIdIn(chartResultDTO);
            chartResultVO = chartResultService.chartPenetrateResult(chartResultDTO);
        }
        return chartResultVO;
    }
}
